/**
 * Copyright (C) 2011 Audit Logger Project. All rights reserved.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.auditlogger.security;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;

import org.auditlogger.config.ConfigurationServices;
import org.auditlogger.config.spi.PropertiesConfigurator;
import org.auditlogger.util.Base64EncoderDecoder;

/**
 * Creates a signature that generates with the MAC value for each 
 * log record/entry
 * 
 * See this: http://download.oracle.com/javase/tutorial/security/apisign/step2.html
 * 
 * @author shardr
 */
class Signer {
	
	private static PropertiesConfigurator config = ConfigurationServices.getPropertiesConfigurator();
	
	private static Signature getSignatureObject() throws NoSuchAlgorithmException {
		Signature dsa = Signature.getInstance("SHA1withDSA");
		return dsa;
	}
	
	private static void initializeSignatureObject(Signature signature, PrivateKey key) 
	           throws InvalidKeyException {
		signature.initSign(key);
	}
	
	private static PrivateKey getSavedSigningPrivateKey() {
		return config.getSignerPrivateKey();
	}
	
	private static byte[] sign(Signature signer, byte[] input) 
	               throws SignatureException {
		signer.update(input);
		return signer.sign();
	}
	
	public static String sign(String inputText) {
		try {
		    Signature signature = getSignatureObject();
		    PrivateKey key = getSavedSigningPrivateKey();
		    initializeSignatureObject (signature, key);
		    byte[] signedBytes = sign (signature, inputText.getBytes());
		    return Base64EncoderDecoder.encodeForBase64(signedBytes);
		} catch (Exception e) {
			throw new EncryptionException (e.getMessage(), e);
		}
	}
	
	public static void main (String[] args) {
		System.out.println(Signer.sign("Ravi Sharda"));
	}
	
	/*
	
	private static PrivateKey privateKey = null;
	private static PublicKey publicKey = null;
	private static String signatureAlgorithm = "SHA1withDSA";
	private static String randomAlgorithm = "SHA1PRNG";
	private static int signatureKeyLength = 1024;
	private static SecureRandom prng = null;
	
	static {
		try {
			privateKey = config.getSigningPrivateKey();
		} catch (Exception e) {
			throw new ExceptionInInitializerError(e);
		}
	}
	
	public static String sign(String message) {
		try {
			Signature signer = Signature.getInstance(signatureAlgorithm);
			signer.initSign(privateKey);
			signer.update(message.getBytes(config.defaultEncoding()));
			byte[] signature = signer.sign();
			return new String(signature);
			// return EncoderDecoder.encodeForBase64(bytes);
		} catch (InvalidKeyException ike) {
			throw new EncryptionException("Encryption failure " 
					+ "Must install unlimited strength crypto extension from Sun", ike);
		} catch (Exception e) {
			throw new EncryptionException("Signature failure" 
					+ "Can't find signature algorithm " + signatureAlgorithm, e);
		}
	}
	
	public boolean verifySignature(String signature, String data) {
		try {
			byte[] bytes = EncoderDecoder.decodeFromBase64(signature);
			Signature signer = Signature.getInstance(signatureAlgorithm);
			signer.initVerify(publicKey);
			signer.update(data.getBytes(config.defaultEncoding()));
			return signer.verify(bytes);
		} catch (Exception e) {
		    // NOTE: EncryptionException constructed *only* for side-effect of causing logging.
		    // FindBugs complains about this and since it examines byte-code, there's no way to
		    // shut it up.
			new EncryptionException("Invalid signature" 
					+ "Problem verifying signature: " + e.getMessage(), e);
			return false;
		}
	}
	
	public static void main (String[] args) {
		Signer.sign("Ravi Sharda");
	}*/

}
